# -*- coding:utf-8 -*-

from typing import List, Union
from datetime import datetime, time

from sqlalchemy.orm import selectinload

from module_admin.entity.do.role_do import SysRoleDept
from sqlalchemy import and_, delete, desc, func, or_, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from module_gen.constants.gen_constants import GenConstants
from module_product.entity.do.bg_product_do import BgProduct
from module_product.entity.do.bg_product_price_do import BgProductPrice
from module_product.entity.vo.bg_product_vo import BgProductPageModel, BgProductModel
from utils.page_util import PageUtil, PageResponseModel
from utils.common_util import CamelCaseUtil


class BgProductDao:

    @classmethod
    async def get_by_id(cls, db: AsyncSession, bg_product_id: int) -> BgProduct:
        """根据主键获取单条记录"""
        bg_product = (((await db.execute(
                            select(BgProduct)
                            .where(BgProduct.id == bg_product_id)))
                       .scalars())
                       .first())
        return bg_product

    """
    查询
    """
    @classmethod
    async def get_bg_product_list(cls, db: AsyncSession,
                             query_object: BgProductPageModel,
                             data_scope_sql: str = None,
                             is_page: bool = False) -> Union[List, PageResponseModel]:

        query = (
            select(BgProduct)
            .options(selectinload(BgProduct.prices).load_only(
                BgProductPrice.random_price # 只加载 id 和 random_price
            ))
            .where(
                BgProduct.name.like(f"%{query_object.name}%") if query_object.name else True,
                BgProduct.status == query_object.status if query_object.status else True,
                BgProduct.is_popular == query_object.is_popular if query_object.is_popular is not None else True,
                BgProduct.del_flag == '0',
                eval(data_scope_sql) if data_scope_sql else True,
            )
            .order_by(BgProduct.index, desc(BgProduct.create_time))
            .distinct()
        )
        bg_product_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
        
        return bg_product_list


    @classmethod
    async def add_bg_product(cls, db: AsyncSession, add_model: BgProductModel, auto_commit: bool = True) -> BgProductModel:
        """
        增加
        """
        bg_product =  BgProduct(**add_model.model_dump(exclude_unset=True, ))
        db.add(bg_product)
        await db.flush()
        bg_product_model = BgProductModel(**CamelCaseUtil.transform_result(bg_product))
        if auto_commit:
            await db.commit()
        return bg_product_model

    @classmethod
    async def edit_bg_product(cls, db: AsyncSession, edit_model: BgProductModel, auto_commit: bool = True) -> BgProduct:
        """
        修改
        """
        edit_dict_data = edit_model.model_dump(exclude_unset=True, exclude={ *GenConstants.DAO_COLUMN_NOT_EDIT })
        await db.execute(update(BgProduct), [edit_dict_data])
        await db.flush()
        if auto_commit:
            await db.commit()
        return await cls.get_by_id(db, edit_model.id)

    @classmethod
    async def del_bg_product(cls, db: AsyncSession, bg_product_ids: List[str], soft_del: bool = True, auto_commit: bool = True):
        """
        删除
        """
        if soft_del:
            await db.execute(update(BgProduct).where(BgProduct.id.in_(bg_product_ids)).values(del_flag='2'))
        else:
            await db.execute(delete(BgProduct).where(BgProduct.id.in_(bg_product_ids)))
        await db.flush()
        if auto_commit:
            await db.commit()

    @classmethod
    async def get_popular_products(cls, db: AsyncSession, limit: int = 3) -> List[dict]:
        """
        获取热门套餐
        """
        query = (
            select(BgProduct)
            .where(
                BgProduct.is_popular == '1',
                BgProduct.status == '0',
                BgProduct.del_flag == '0'
            )
            .order_by(BgProduct.index, desc(BgProduct.create_time))
            .limit(limit)
        )
        
        result = await db.execute(query)
        products = result.scalars().all()
        product_list = CamelCaseUtil.transform_result(products)
        return product_list


